package com.leetcode;

/**
 * <p>
 * 【题目】：leetcode第887题 。 动态规划求解
 * 你将获得 K 个鸡蛋，并可以使用一栋从 1 到 N  共有 N 层楼的建筑。每个蛋的功能都是一样的，如果一个蛋碎了，你就不能再把它掉下去。
 * 你知道存在楼层 F ，满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎，从 F 楼层或比它低的楼层落下的鸡蛋都不会破。
 * 每次移动，你可以取一个鸡蛋（如果你有完整的鸡蛋）并把它从任一楼层 X 扔下（满足 1 <= X <= N）。你的目标是确切地知道 F 的值是多少。
 * 无论 F 的初始值如何，你确定 F 的值的最小移动次数是多少？
 * <p>
 * 示例 1：
 * 输入：K = 1, N = 2
 * 输出：2
 * 解释：
 * 鸡蛋从 1 楼掉落。如果它碎了，我们肯定知道 F = 0 。
 * 否则，鸡蛋从 2 楼掉落。如果它碎了，我们肯定知道 F = 1 。
 * 如果它没碎，那么我们肯定知道 F = 2 。
 * 因此，在最坏的情况下我们需要移动 2 次以确定 F 是多少。
 * <p>
 * 示例 2：
 * 输入：K = 2, N = 6
 * 输出：3
 * <p>
 * 示例 3：
 * 输入：K = 3, N = 14
 * 输出：4
 *  
 * <p>
 * 提示：
 * 1 <= K <= 100
 * 1 <= N <= 10000
 *
 * </p>
 *
 *
 * 解题思路参考：https://blog.nowcoder.net/n/d31ec70a9300451aacc528ae6b69cb92?from=nowcoder_improve
 *
 * @author: Sunny
 * @date: 2021/2/24
 * @version: v1.0.0
 */
public class EggDrop {

    public static void main(String[] args) {
        EggDrop eggDrop = new EggDrop();
        System.out.println(eggDrop.superEggDrop(1, 2));
    }

    public int superEggDrop(int K, int N) {
        /**
         * N
         * N-1
         * .
         * K
         * .
         * .
         * 1
         *
         * 从下到上一共是N层，1到N层。
         */

        /**
         * 定义dp[k][m]表示k个鸡蛋在m步内可以测试的层数
         * 当在第i层扔一个鸡蛋，使用了一步，有两种情况：
         * 1.鸡蛋碎了：上面的楼层测试完毕，接下来在更低的楼层试，最多能测试i-1+dp[k-1][m-1]层；
         * 2.鸡蛋没碎：下面的楼层测试完毕，接下来在更高的楼层试，最多能测试N-i+dp[k][m-1]层；
         * 因此如果有k个鸡蛋和m步，并且在第i层扔鸡蛋，最多可测试的层数：
         * dp[k-1][m-1]+dp[k][m-1]+1
         * 可以用一维数据代替二维dp
         */
        int[] dp = new int[K + 1];
        for (int m = 1; m <= N; m++) {
            for (int i = K; i > 0; i--) {
                dp[i] = dp[i - 1] + dp[i] + 1;
                if (dp[i] >= N) {
                    return m;
                }
            }
        }
        return N;
    }

}
